package gew.beans;

import gew.data.TradeSummaryItem;
import gew.data.TreeItem;
import gew.metadata.CustomSql;
import gew.metadata.Queries;
import gew.sql.SqlTemplates;
import gew.system.Constants;
import gew.system.Labels;
import gew.system.RequestParameter;
import gew.utils.SqlUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

@ManagedBean(name = "tradeSummaryBean")
@RequestScoped
public class TradeSummaryBean extends BaseBean {

    private RequestParameter rp;

    private Integer defaultPartnerId;
    private Integer defaultCommodityClassificationId;
    private Integer defaultCommodityId;
    private String defaultCommodityClassificationCode;
    private String defaultPartnerUrlCode;
    private String defaultCommodityClassificationUrlCode;
    private String defaultCommodityUrlCode;
    private String defaultPartnerName;
    private String defaultCommodityCode;
    private String defaultCommodityName;
    private String importUrlCode;
    private String exportUrlCode;
    private String importTitle;
    private String exportTitle;
    private String reporterTitle;
    private String partnerTitle;
    private String periodTitle;
    private String tradeFlowTitle;
    private String tradeValueTitle;
    private String shareOfTotalTitle;
    private String commodityTitle;
    private String tradeBaseUrl;
    private String groupDelimiter;
    private String decimalDelimiter;
    private List<TreeItem> classifications;
    private ArrayList<String> reporterNamesGen;
    private ArrayList<String> reporterPeriods;

    private List<TradeSummaryItem> tradeSummaryTableData;

    public RequestParameter getRequestParameter() {
        return rp;
    }

    public Integer getDefaultPartnerId() {
        return defaultPartnerId;
    }

    public Integer getDefaultCommodityClassificationId() {
        return defaultCommodityClassificationId;
    }

    public Integer getDefaultCommodityId() {
        return defaultCommodityId;
    }

    @PostConstruct
    public void init() {
        HttpServletRequest r = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        rp = new RequestParameter(r, dvs);
        logRequest(r, Constants.SECTION_TRADE_SUMMARY, rp.getRequestURI());
        defaultPartnerId = df.getSingleResult(SqlTemplates.getSql(SqlTemplates.TRADE_SUMMARY_DEFAULT_PARTNER));
        defaultPartnerUrlCode = dvs.getUrlCodeById(Queries.CountryDimensionValue, defaultPartnerId, rp.getLocale());
        defaultPartnerName = dvs.getNameById(Queries.CountryDimensionValue, defaultPartnerId, rp.getLocale());
        //defaultCommodityClassificationId = dataFacade2.getSingleResult(SqlTemplates.getSql(SqlTemplates.TRADE_SUMMARY_DEFAULT_COMMODITY_CLASSIFICATION));
        defaultCommodityClassificationId = rp.getCommodityGroupTypeIds().size() > 0
                ? rp.getCommodityGroupTypeIds().get(0)
                : df.getSingleResult(SqlTemplates.getSql(SqlTemplates.TRADE_SUMMARY_DEFAULT_COMMODITY_CLASSIFICATION));
        defaultCommodityClassificationUrlCode = dvs.getUrlCodeById(Queries.CommodityGroupTypeDimensionValue, defaultCommodityClassificationId, rp.getLocale());
        defaultCommodityClassificationCode = dvs.getNameById(Queries.CommodityGroupTypeDimensionValue, defaultCommodityClassificationId, rp.getLocale());

        defaultCommodityId = df.getSingleResult(CustomSql.getTradeSummaryDefaultCommodity(defaultCommodityClassificationId.toString()));
        defaultCommodityUrlCode = dvs.getUrlCodeById(Queries.CommodityDimensionValue, defaultCommodityId, rp.getLocale());
        defaultCommodityCode = dvs.getCodeById(Queries.CommodityDimensionValue, defaultCommodityId, rp.getLocale());
        defaultCommodityName = dvs.getNameById(Queries.CommodityDimensionValue, defaultCommodityId, rp.getLocale());
        importUrlCode = dvs.getUrlCodeById(Queries.TradeFlowDimensionValue, Constants.DIM_TRADE_FLOW_IMPORT_ID, rp.getLocale());
        exportUrlCode = dvs.getUrlCodeById(Queries.TradeFlowDimensionValue, Constants.DIM_TRADE_FLOW_EXPORT_ID, rp.getLocale());
        importTitle = dvs.getNameById(Queries.TradeFlowDimensionValue, Constants.DIM_TRADE_FLOW_IMPORT_ID, rp.getLocale());
        exportTitle = dvs.getNameById(Queries.TradeFlowDimensionValue, Constants.DIM_TRADE_FLOW_EXPORT_ID, rp.getLocale());
        tradeBaseUrl = SqlUtils.SLASH
                .concat(rp.getLocaleUrlCode())
                .concat(SqlUtils.SLASH)
                .concat(Constants.SECTION_TRADE)
                .concat(SqlUtils.SLASH);
        reporterTitle = Labels.get_UI_TITLE_REPORTER(rp.getLocale());
        partnerTitle = Labels.get_UI_TITLE_PARTNER(rp.getLocale());
        periodTitle = Labels.get_UI_TITLE_PERIOD(rp.getLocale());
        tradeValueTitle = Labels.get_UI_TITLE_TRADE_VALUE(rp.getLocale());
        shareOfTotalTitle = Labels.get_UI_TITLE_TRADE_SHARE_TOTAL(rp.getLocale());
        commodityTitle = Labels.get_UI_TITLE_COMMODITY(rp.getLocale());
        tradeFlowTitle = Labels.get_UI_TITLE_TRADE_FLOW(rp.getLocale());
        groupDelimiter = Labels.get_UI_GROUP_DELIMITER(rp.getLocale());
        decimalDelimiter = Labels.get_UI_DECIMAL_DELIMITER(rp.getLocale());

        String urlBegin = rp.getContextPath()
                .concat(SqlUtils.SLASH)
                .concat(rp.getLocaleUrlCode())
                .concat(SqlUtils.SLASH)
                .concat(Constants.SECTION_TRADE_SUMMARY)
                .concat(SqlUtils.SLASH);

        String urlEnd = SqlUtils.SLASH
                .concat(rp.getReporterUrlCode());

        String q1 = CustomSql.getTree2Init(rp.getLocaleUrlCode(),
                ((Integer) Constants.HIER_GROUP_COMMODITY_CLASSIFICATION).toString(),
                defaultCommodityClassificationId.toString(),
                urlBegin, SqlUtils.EMPTY, urlEnd);
        classifications = df.getTreeItems(q1);

        reporterPeriods = new ArrayList<>();
        reporterNamesGen = new ArrayList<>();
        q1 = CustomSql.getTradeSummaryTable(rp.isReporterUrlCodeIsDefault() ? "0" : rp.getReporterIdsCS(), defaultPartnerId, defaultCommodityId, tradeBaseUrl, exportUrlCode, importUrlCode, defaultPartnerUrlCode, defaultCommodityClassificationUrlCode, defaultCommodityUrlCode, rp.getLocaleUrlCode());
        tradeSummaryTableData = df.getTradeSummaryItems(q1);
        for (TradeSummaryItem item : tradeSummaryTableData) {
            item.setLocale(rp.getLocale());
            item.setNumberFormat(rp.getNumberFormat());
            item.setPercentFormat(rp.getPercentFormat());
            if (item.getLvl() == 1 && item.getOpen() == 1) {
                if (!reporterPeriods.contains(item.getLastPeriodId().toString())) {
                    reporterPeriods.add(item.getLastPeriodId().toString());
                }
                reporterNamesGen.add(dvs.getNameGenById(Queries.CountryDimensionValue, item.getId(), rp.getLocale()));
            }
        }
    }

    static String getTitle(boolean includeMainTitle, Locale locale, String countryAllNAmes) {
        StringBuilder buf = new StringBuilder();
        buf
                .append(Labels.get_UI_TITLE_TRADE_SUMMARY(locale));
        if (!SqlUtils.EMPTY.equals(countryAllNAmes)) {
            buf
                    .append(SqlUtils.SPACE)
                    .append(SqlUtils.HYPHEN)
                    .append(SqlUtils.SPACE)
                    .append(countryAllNAmes);
        }
        if (includeMainTitle) {
            buf
                    .append(SqlUtils.SPACE)
                    .append(SqlUtils.VERTICAL_BAR)
                    .append(SqlUtils.SPACE)
                    .append(Labels.get_UI_TITLE_MAIN_SHORT(locale));
        }
        return buf.toString();
    }

    public String getPageTitle() {
        return getTitle(true, rp.getLocale(), dvs.getAllNames(Queries.CountryDimensionValue, rp.getReporterIds(), rp.getLocale()));
    }

    public String getShortTitle() {
        return getTitle(false, rp.getLocale(), dvs.getAllNames(Queries.CountryDimensionValue, rp.getReporterIds(), rp.getLocale()));
    }

    public List<TradeSummaryItem> getTradeSummaryTableData() {
        return tradeSummaryTableData;
    }

    public String getSwitchLanguageUrl(String locale) {
        return rp.getContextPath()
                .concat(SqlUtils.SLASH)
                .concat(locale)
                .concat(SqlUtils.SLASH)
                .concat(Constants.SECTION_TRADE_SUMMARY)
                .concat(SqlUtils.SLASH)
                .concat(rp.getReporterIds().isEmpty() ? "" : rp.getReporterUrlCode());
    }

    public String getLocaleUrlCode() {
        return rp.getLocaleUrlCode();
    }

    public String getContextPath() {
        return rp.getContextPath();
    }

    public String getExportTitle() {
        return this.exportTitle;
    }

    public String getImportTitle() {
        return this.importTitle;
    }

    public String getReporterTitle() {
        return reporterTitle;
    }

    public String getPartnerTitle() {
        return partnerTitle;
    }

    public String getPeriodTitle() {
        return periodTitle;
    }

    public String getTradeValueTitle() {
        return tradeValueTitle;
    }

    public String getShareOfTotalTitle() {
        return shareOfTotalTitle;
    }

    public String getCommodityTitle() {
        return commodityTitle;
    }

    public String getTradeBaseUrl() {
        return tradeBaseUrl;
    }

    public String getTradeFlowTitle() {
        return tradeFlowTitle;
    }

    public String getDefaultPartnerName() {
        return defaultPartnerName;
    }

    public String getDefaultCommodityCode() {
        return defaultCommodityCode;
    }

    public String getDefaultCommodityName() {
        return defaultCommodityName;
    }

    public String getGroupDelimeter() {
        return groupDelimiter;
    }

    public String getDecimalDelimeter() {
        return decimalDelimiter;
    }

    public String getDefaultCommodityClassificationCode() {
        return defaultCommodityClassificationCode;
    }

    public String getExpandUrl(String urlCode, byte open, int lvl, int id) {
        String reporterUrls = rp.isReporterUrlCodeIsDefault() ? "" : rp.getReporterUrlCode();
        String bookmark = SqlUtils.EMPTY;
        switch (open) {
            case 0: {
                if (rp.isReporterUrlCodeIsDefault()) {
                    reporterUrls = urlCode;
                } else {
                    String[] urls = Arrays.copyOf(rp.getReporterUrlCodes(),
                            rp.getReporterUrlCodes().length + 1);
                    urls[urls.length - 1] = urlCode;
                    Arrays.sort(urls);
                    reporterUrls = String.join(SqlUtils.HYPHEN, urls);
                }
                bookmark = SqlUtils.OCTOTHORPE.concat(urlCode);
            }
            break;
            case 1: {
                switch (lvl) {
                    case 0: {
                        String q1 = CustomSql.getPartnerUrlCollapse(
                                rp.isReporterUrlCodeIsDefault()
                                        ? "-1"
                                        : rp.getReporterIdsCS(),
                                id);
                        reporterUrls = df.getSqlQuerySingleResult(q1).toString();
                    }
                    break;
                    case 1: {
                        reporterUrls = "";
                        for (int i = 0; i < rp.getReporterUrlCodes().length; i++) {
                            if (rp.getReporterUrlCodes()[i] == null ? urlCode != null : !rp.getReporterUrlCodes()[i].equals(urlCode)) {
                                if (reporterUrls.length() > 0) {
                                    reporterUrls = reporterUrls.concat(SqlUtils.HYPHEN);
                                }
                                reporterUrls = reporterUrls.concat(rp.getReporterUrlCodes()[i]);
                            }
                        }
                    }
                    break;
                }
            }
        }
        return rp.getContextPath()
                .concat(SqlUtils.SLASH)
                .concat(rp.getLocaleUrlCode())
                .concat(SqlUtils.SLASH)
                .concat(Constants.SECTION_TRADE_SUMMARY)
                .concat(SqlUtils.SLASH)
                .concat(defaultCommodityClassificationUrlCode)
                .concat(SqlUtils.SLASH)
                .concat(reporterUrls)
                .concat(bookmark);
    }

    private String getDetailsUrl(boolean isGroupPartner, String reporterUrlCode, String periodUrlCode, String tradeFlowUrlCode, String urlCode) {
        if (isGroupPartner) {
            return rp.getContextPath()
                    .concat(SqlUtils.SLASH)
                    .concat(rp.getLocaleUrlCode())
                    .concat(SqlUtils.SLASH)
                    .concat(Constants.SECTION_TRADE)
                    .concat(SqlUtils.SLASH)
                    .concat(reporterUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(tradeFlowUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(urlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(periodUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(this.defaultCommodityClassificationUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(this.defaultCommodityUrlCode);
        } else {
            return rp.getContextPath()
                    .concat(SqlUtils.SLASH)
                    .concat(rp.getLocaleUrlCode())
                    .concat(SqlUtils.SLASH)
                    .concat(Constants.SECTION_TRADE)
                    .concat(SqlUtils.SLASH)
                    .concat(reporterUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(tradeFlowUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(this.defaultPartnerUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(periodUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(this.defaultCommodityClassificationUrlCode)
                    .concat(SqlUtils.SLASH)
                    .concat(urlCode);
        }
    }

    public String getDetailsExportUrl(boolean isGroupPartner, String reporterUrlCode, String periodUrlCode, String urlCode) {
        return getDetailsUrl(isGroupPartner, reporterUrlCode, periodUrlCode, this.exportUrlCode, urlCode);
    }

    public String getDetailsImportUrl(boolean isGroupPartner, String reporterUrlCode, String periodUrlCode, String urlCode) {
        return getDetailsUrl(isGroupPartner, reporterUrlCode, periodUrlCode, this.importUrlCode, urlCode);
    }

    public String getUI_FOOTER_TRADE() {
        return Labels.get_UI_FOOTER_TRADE(rp.getLocale());
    }

    public List<TreeItem> getClassifications() {
        return classifications;
    }

    public String getUI_TITLE_SOURCES() {
        return Labels.get_UI_TITLE_SOURCES(rp.getLocale());
    }

    public String getHttpHeader() {
        return rp.getHttpHeader();
    }

    public String getKeyWords() {
        return Labels.get_META_KEY_WORDS_TRADE_SUMMARY(rp.getLocale())
                .concat(SqlUtils.COMMA).concat(SqlUtils.SPACE)
                .concat(dvs.getAllNames(Queries.CountryDimensionValue, rp.getReporterIds(), rp.getLocale(), SqlUtils.COMMA.concat(SqlUtils.SPACE)))
                .concat(SqlUtils.COMMA).concat(SqlUtils.SPACE)
                .concat(String.join(SqlUtils.COMMA.concat(SqlUtils.SPACE), reporterPeriods))
                .concat(SqlUtils.COMMA).concat(SqlUtils.SPACE)
                .concat(defaultCommodityClassificationCode);
    }

    public String getReporterNamesGen() {
        return String.join(SqlUtils.COMMA.concat(SqlUtils.SPACE), reporterNamesGen);
    }

    public String getReporterPeriods() {
        return String.join(SqlUtils.COMMA.concat(SqlUtils.SPACE), reporterPeriods);
    }

    static String getDescription(Locale locale, String selectedReporterNamesGen, String selectedClassification) {
        return Labels.get_UI_DESCRIPTION_SEARCH_TRADE_SUMMARY(locale)
                .replace("[reporterNamesGen]", selectedReporterNamesGen)
                .replace("[classification]", selectedClassification);
    }

    public String getDescription() {
        return getDescription(
                rp.getLocale(),
                dvs.getAllNamesGen(Queries.CountryDimensionValue, rp.getReporterIds(), rp.getLocale()),
                dvs.getNameById(Queries.CommodityGroupTypeDimensionValue, defaultCommodityClassificationId, rp.getLocale())
        );
    }

    static String getUrl(String contextPath, String localeUrlCode, String classificationUrlCode, String reporterUrlCode) {
        StringBuilder buf = new StringBuilder();
        buf
                .append(contextPath)
                .append(SqlUtils.SLASH)
                .append(localeUrlCode)
                .append(SqlUtils.SLASH)
                .append(Constants.SECTION_TRADE_SUMMARY)
                .append(SqlUtils.SLASH)
                .append(classificationUrlCode)
                .append(SqlUtils.SLASH)
                .append(reporterUrlCode);
        return buf.toString();
    }
}
